package com.unrarme.api.vkontakte
{
	import com.unrarme.utils.string.CUtils;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLRequestHeader;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	
	import mx.collections.ArrayCollection;
	import mx.rpc.events.ResultEvent;
	
	public class Vk extends EventDispatcher
	{
		private var username:String;
		private var password:String;
		
		private var loader:URLLoader = new URLLoader();
		private var request:URLRequest = new URLRequest();
		
		private var logged:Boolean = false;
		
		private var videoSearchParameters:*;
		
		private var quality:Dictionary;
		
		public function Vk(username:String, password:String)
		{
			this.quality = new Dictionary();
			this.quality["0"] = "240";
			this.quality["1"] = "360";
			this.quality["2"] = "480";
			this.quality["3"] = "720";
			
			this.username = username;
			this.password = password;
			
			loader.dataFormat = URLLoaderDataFormat.BINARY;
			
			request.requestHeaders['Referer'] = "http://vkontakte.ru/";
			request.url = 'http://vkontakte.ru/';
			
			loader.addEventListener(Event.COMPLETE, checkLoginHandler);
			loader.load(request);
		}
		
		private function getLoaderData():String {
			var ba:ByteArray = this.loader.data;
			return new String(ba.readMultiByte(ba.length, 'windows-1251'));
		}
		
		private function checkLoginHandler(e:Event):void {
			loader.removeEventListener(Event.COMPLETE, checkLoginHandler);
			var data:String = this.getLoaderData();
			
			if(data.match('id="myfriends"') == null){
				var vars:URLVariables = new URLVariables();
				vars.op = "a_login_attempt";
				
				request.url = "http://vkontakte.ru/login.php";
				request.method = URLRequestMethod.POST;
				request.requestHeaders.push(new URLRequestHeader('X-Requested-With','XMLHttpRequest'));
				request.data = vars;
				
				// add event listener and load url
				loader.addEventListener(Event.COMPLETE, firstLoginLoadHandler);
				loader.load(request);
			} else {
				logged = true;
				dispatchEvent(new Event(VkEvent.LOGGED));
			}
		}
		
		private function firstLoginLoadHandler(e:Event):void {
			loader.removeEventListener(Event.COMPLETE, firstLoginLoadHandler);
			var data:String = this.getLoaderData();
						
			// create vars
			var vars:URLVariables = new URLVariables();
			vars.email = this.username;
			vars.pass = this.password;
			vars.expire = '1';
			vars.al_test = '1';
			vars.vk = '';
			
			// create urlrequester and urlloader
			request.url = "http://login.vk.com/?act=login";
			request.method = URLRequestMethod.POST;
			request.requestHeaders.push(new URLRequestHeader('X-Requested-With','XMLHttpRequest'));
			request.data = vars;
			
			// add event listener and load url
			loader.addEventListener(Event.COMPLETE, secondLoginLoadHandler);
			loader.load(request);
		}
		
		private function secondLoginLoadHandler(e:Event):void {
			loader.removeEventListener(Event.COMPLETE, secondLoginLoadHandler);
			var data:String = this.getLoaderData();
			
			var vars:URLVariables = new URLVariables();
			
			var re:RegExp = new RegExp(/<input type=['|"]hidden['|"] name=['|"](.+?)['|"] value=['|"](.*?)['|"] \/>/gs);
			var res:Array = re.exec(data);
			while(res != null){
				vars[res[1]] = res[2];
				res = re.exec(data);
			}
			
			// create urlrequester and urlloader
			request.url = "http://vkontakte.ru/login.php";
			request.method = URLRequestMethod.POST;
			request.requestHeaders.push(new URLRequestHeader('X-Requested-With','XMLHttpRequest'));
			request.data = vars;
			
			// add event listener and load url
			loader.addEventListener(Event.COMPLETE, finalLoginLoadHandler);
			loader.load(request);
		}
		
		private function finalLoginLoadHandler(e:Event):void {
			loader.removeEventListener(Event.COMPLETE, finalLoginLoadHandler);
			var data:String = this.getLoaderData();
			
			if(data.match('forgotPass') != null){
				//dispatchError("Неверный логин или пароль вконтакте!");
				trace('Wrong password or username to Vkontakte.ru')
			}else{
				trace('Logged into Vkontakte.ru');
				logged = true;
				dispatchEvent(new Event(VkEvent.LOGGED));
			}
			data = null;
		}
		
		public function videoSearch(query:String, quality:Number = 0, duration:Number = 0, pages:Number = 1): void {
			this.videoSearchParameters = { 'duration': duration, 'quality': quality, 'pages': pages };
			// http://vkontakte.ru/gsearch.php?section=video&q=%D0%94%D0%BE%D0%BA%D1%82%D0%BE%D1%80+%D0%A5%D0%B0%D1%83%D1%81&name=1&ajax=1
			request.url = "http://vkontakte.ru/gsearch.php?section=video&q="+flash.utils.escapeMultiByte(query)+"&name=1&ajax=1";			
			loader.addEventListener(Event.COMPLETE, firstVideoSearchHandler);
			
			var vars:URLVariables = new URLVariables();
			vars['c[q]'] = query;
			if(this.videoSearchParameters.quality > 0){
				vars['c[hd]'] = "1";
				//vars['c[quality]'] = hd.toString();
			}
			vars['c[section]'] = "video";
			//vars['c[sort]'] = "1";
			//vars.offset = 0;
			vars.auto = 1;
			vars.preload = 1;
			vars.offset = 0;
			vars.count = 100;
			
			request.method = URLRequestMethod.POST;
			request.data = vars;
			request.requestHeaders['Referer'] = "http://vkontakte.ru/gsearch.php?q="+flash.utils.escapeMultiByte(query)+"&section=video&name=1&offset=1";
			
			// remove default error cathcer
			//loader.removeEventListener(IOErrorEvent.IO_ERROR, onError);
			// add speacial
			//myLoader.addEventListener(IOErrorEvent.IO_ERROR, onTrackError);
			
			// load request
			loader.load(request);
		}
		
		
		private function firstVideoSearchHandler(e:Event) {
			loader.removeEventListener(Event.COMPLETE, firstVideoSearchHandler);
			var data:String = loader.data;

			var ve:VkEvent = new VkEvent(VkEvent.VIDEO_FOUND);
			ve.data = getVideos(data);
			
			dispatchEvent(ve);
		}
		
		private function getVideos(data:String):ArrayCollection {
			var re:RegExp;
			var res:Array;
			
			data = data.replace(/\n/gs, "").replace(/\t/gs, "").replace(/\r/gs, "");
			data = data.replace(/\\n/gs, "").replace(/\\t/gs, "").replace(/\\r/gs, "");
			data = data.replace(/\\"/gs, '"');
			data = data.replace(/\\\//gs, "/");
			data = data.replace(/\\\\\//gs, "/");
			
			data = CUtils.prepareVkVideoTitle(data);
			
			re = new RegExp(/"uid":"(.+?)".+?"host":"(.+?)".+?"vtag":"(.+?)".+?"ltag":"(.+?)".+?"md_title":"(.+?)".+?"hd":(.+?),.+?"thumb":"(.+?)".+?(class="ainfo".+?style=.color:#000.>(.+?)<\/b>|<\/td.?+\/tr><\/table>)/gs);
			res = re.exec(data);
			var info:Object;
			var results:ArrayCollection = new ArrayCollection();
			
			while(res != null){				
				if(String(res[1]).length < 3){
					res = re.exec(data);
					continue;
				}
				res['input'] = '';
				res[0] = '';
				
				var duration:int = 0;
				if (res[9] != null) {
					duration = (String(res[9]).split(":").length > 2)?(int(String(res[9]).split(":")[0]) * 60) + int(String(res[9]).split(":")[1]):int(String(res[9]).split(":")[0]);
				}
				trace(res[5] + ' Lencalc: ' + duration + " finddur: " + this.videoSearchParameters.duration);
				
				if(res[9] != null && (duration > (this.videoSearchParameters.duration - 15)) && (duration < (this.videoSearchParameters.duration + 15))){
				//if(res[9] != null){
					info = new Object();
					info.uid = res[1];
					info.host = res[2];
					info.vtag = res[3];
					info.ltag = res[4];
					info.title = res[5];
					info.hd = res[6];
					info.thumb = res[7];
					info.len = (res[9]==null)?"?:??":res[9];
					if(info.hd == 0){
						info.url = info.host+'u'+info.uid+'/video/'+
							info.vtag+'.flv';
						info.hd_text = "260p";
					} else {
						info.urls = new Array();
						
						for (var i:int = info.hd; i > 0; i--) {
							info.urls[i] = info.host+'u'+info.uid+'/video/'+ info.vtag+'.'+this.quality[i]+'.mp4'; 						
						}
						info.urls[0] = info.host+'u'+info.uid+'/video/'+ info.vtag+'.flv';
						info.url = info.host+'u'+info.uid+'/video/'+ info.vtag+'.'+this.quality[info.hd]+'.mp4';
						info.hd_text = this.quality[info.hd]+"p";
						
					}
					
					// add res
					results.addItem(info);
				}
				
				res = re.exec(data);
			}
			
			// erase vars
			//dupes = null;
			info = null;
			data = null;
			re = null;
			res = null;
			
			return results;
		}
	}
}